Packer x Terraform x StaticPress で静的コンテンツ配信システムをテンプレート化してみた
はじめに
こんにちは、中山です。
StaticPressを利用した静的コンテンツの配信システムをPacker/Terraformを利用してテンプレート化してみました。以下のようなことができるシステムを作れます。
- WordPressで記事を作成
- StaticPress S3プラグインでS3にアップロード
- CloudFrontで配信
- Route53で名前解決
WordPressを使いたいけど静的サイトも興味がある。でも、HugoとかJekllyはよう分からん。あとCDNよろ。そんなわがままボディなお悩みを解決できるかと思います。
作成するAWSリソースは以下のとおりです。
AWSリソース | 用途 |
---|---|
VPC環境 | EC2インスタンスを起動させるため |
EC2 | WordPressで記事を作成後S3にアップロードさせるため |
S3 | 静的コンテンツを配信するため |
Route53 | EC2/S3/CloudFrontの名前解決を実施するため |
CloudFront | S3上のオリジンコンテンツをキャッシュさせるため |
構成図
テンプレートのソースコード
作成したコードはGitHubに上げておきました。本エントリで参照しているコミットハッシュ値は 7ae5b1b01bf261fdd447d7fd3f89dd655fbb85d0
です。HEADが更新された場合は内容に差異が発生している可能性があるのでご注意ください。
使い方
以下にテンプレートの使用方法を記載します。
KeyPairの作成
EC2インスタンスにSSHでログインするためのKeyPairを作成します。 <key-name>
は任意の名前に変更してください。
$ aws ec2 create-key-pair --key-name <key-name> --query 'KeyMaterial' --output text > ~/.ssh/<key-name> && chmod 400 ~/.ssh/<key-name>
ツールのインストール
このリポジトリで利用している各種ツールを事前にインストールしてください。
$ gem install bundler $ pip install cookiecutter $ brew cask install packer terraform
リポジトリのclone
cookiecutterでリポジトリをcloneします。cloneするとサイトのドメイン名などを聞かれるので今回の構成に合うよう入力してください。何も入力しない場合はデフォルト値が利用されます。
$ cookiecutter gh:knakayama/static-site-template Cloning into 'static-site-template'... remote: Counting objects: 86, done. remote: Compressing objects: 100% (62/62), done. remote: Total 86 (delta 3), reused 86 (delta 3), pack-reused 0 Unpacking objects: 100% (86/86), done. Checking connectivity... done. project_slug [static-site-template]: region [ap-northeast-1]: profile [default]: keypair_path [~/.ssh/static_site_key_pair]: base_ami_id [ami-f80e0596]: site_domain [example.com]: ***.com wp_sub_domain [wp]: static_site_sub_domain [static]: wp_domain_ttl [60]: static_site_domain_ttl [60]: wp_db_name [wordpress]: wp_db_user [wordpress]: wp_db_pass [pAssw0rd]: wp_site_title [static-site]: wp_site_admin_user [wp-site-admin]: wp_site_admin_password [wp-site-admin-pass]: wp_site_admin_email [wp-site-email@example.com]: ***@***.com wp_instance_type [t2.micro]: wp_volume_size [100]: wp_volume_type [gp2]: cloudfront_price_class [PriceClass_200]: ssh_cidr_blocks [0.0.0.0/0]: stg_source_ip [0.0.0.0/0]: $ cd static-site-template
gemのインストール
PackerとTerraformの実行はコマンドを直接指定するのではなくRakeでタスク化しています。bundlerでRakeなどのgemをインストールしてください。
$ bundle install --path vendor/bundle <snip> Bundle complete! 3 Gemfile dependencies, 9 gems now installed. Bundled gems are installed into ./vendor/bundle.
Rakeのタスクには以下のものがあります。
$ bundle exec rake -T rake packer:build # Build AMI rake packer:validate # Validate Packer template rake terraform:global:apply # Apply Terraform to create IAM Group and Users rake terraform:global:destroy # Destroy IAM Resources rake terraform:global:output # Outpute IAM Resources rake terraform:global:plan # Plan Terraform to create IAM Group and Users rake terraform:global:remote:disable # Disable S3 backend to store IAM tfstate locally rake terraform:global:remote:enable # Enable S3 backend to store IAM tfstate rake terraform:prod:apply # Apply Terraform to create AWS Resources on prod rake terraform:prod:destroy # Destroy AWS Resources on prod rake terraform:prod:output # Outpute AWS Resources on prod rake terraform:prod:plan # Plan Terraform to create AWS Resources on prod rake terraform:prod:remote:disable # Disable S3 backend to store AWS tfstate locally rake terraform:prod:remote:enable # Enable S3 backend to store AWS tfstate
AMIの作成
Packerを使用してAMIを作成します。まずはテンプレートが正しいか確認します。
$ bundle exec rake packer:validate -t ** Invoke packer:validate (first_time) ** Execute packer:validate cd packer && AWS_PROFILE=default packer validate wp.json Template validated successfully.
続いてAMIを作成します。
$ bundle exec rake packer:build -t <snip> ==> wp-ami: No volumes to clean up, skipping ==> wp-ami: Deleting temporary security group... ==> wp-ami: Deleting temporary keypair... Build 'wp-ami' finished. ==> Builds finished. The artifacts of successful builds are: --> wp-ami: AMIs were created: ap-northeast-1: ami-********
Packerが正常に終了するとAMIのIDが表示されるので properties.yml
に追記してください。
$ $EDITOR properties.yml :wp_ami_id: "" <- AMI IDを追記
IAMグループとユーザの作成
StaticPress S3プラグインを利用してS3にコンテンツをアップロードするためのIAMグループとユーザを作成します。まずは plan
を実行してTerraformが作成するAWSリソースを確認します。
$ bundle exec rake terraform:global:plan -t <snip> Plan: 8 to add, 0 to change, 0 to destroy.
上記の例では8つのAWSリソースが新たに作成されることが確認できます。続いて apply
で実際にAWSリソースを作成します。
$ bundle exec rake terraform:global:apply -t <snip> State path: terraform.tfstate Outputs: config = Admin IAM: Admin Users: static-site-admin Access IDs: ******************** Secret Keys: **************************************** iam_admin_access_ids = ******************** iam_admin_secret_keys = **************************************** iam_admin_users = static-site-admin remote_state_bucket = *************************************
tfstate
はS3 Backendを利用してS3上に設置します。
$ bundle exec rake terraform:global:remote:enable -t <snip> Remote state management enabled Remote state configured and pulled.
もしローカルに設置したい場合は以下のようにコマンドを実行してください。
$ bundle exec rake terraform:global:remote:disable -t ** Invoke terraform:global:remote:disable (first_time) ** Execute terraform:global:remote:disable cd terraform/global && AWS_PROFILE=default terraform remote config -disable
続いて、EC2などのAWSリソースを構築します。先程と同じくまずは plan
を実行して作成されるAWSリソースを確認します。
$ bundle exec rake terraform:prod:plan -t <snip> Plan: 28 to add, 0 to change, 0 to destroy.
上記の例では28つのAWSリソースが新たに作成されることが確認できます。続いて apply
で実際にAWSリソースを作成します。
$ bundle exec rake terraform:prod:apply -t <snip> Outputs: cloudfront_domain_name = **************.cloudfront.net remote_state_bucket = static-site-prod-tfstate-****-**-** static_site_cloudfront_fqdn = static.*********.com static_site_prod_fqdn = prod.static.*********.com website_endpoint_prod = prod.static.*********.com.s3-website-ap-northeast-1.amazonaws.com website_endpoint_stg = stg.static.*********.com.s3-website-ap-northeast-1.amazonaws.com wp_fqdn = wp.*********.com wp_public_ip = **.***.*.***
こちらも同様 tfstate
はS3に設置可能です。
$ bundle exec rake terraform:prod:remote:enable -t <snip> Remote state management enabled Remote state configured and pulled.
StaticPressの設定
wp_fqdn
で設定されているドメインの/wordpressにアクセスするとWordPressが表示されます。ログイン後StaticPressとStaticPress S3の設定してください。設定の仕方は参考リンクを参照してください。
StaticPress S3プラグインで指定するAWSクレデンシャルは以下のコマンドで確認できます。
$ bundle exec rake terraform:global:output -t
WordPressにログインする際のクレデンシャルは wp.json
に書いてあります。ちょっと微妙です。
まとめ
いかがだったでしょうか。
インフラをコード化すると一瞬で思い通りのシステムが構築できるのでとても便利ですね。
本エントリがみなさんの参考になったら幸いに思います。